package com.itjin.controller;

import com.itjin.model.domain.dto.CreatePostDTO;
import com.itjin.model.domain.dto.CreateCommentDTO;
import com.itjin.model.domain.dto.PostReportDTO;
import com.itjin.model.domain.dto.IncreasePostHeatDTO;
import com.itjin.model.domain.dto.PostListQueryDTO;
import com.itjin.model.domain.vo.GetPostListVO;
import com.itjin.model.domain.vo.PostLikeVO;
import com.itjin.model.domain.vo.PostDetailVO;
import com.itjin.model.domain.vo.CommentVO;
import com.itjin.model.domain.vo.PostCollectVO;
import com.itjin.model.domain.vo.ReportedPostVO;
import com.itjin.model.domain.vo.PostHeatVO;
import com.itjin.model.result.Result;
import com.itjin.service.PostService;
import lombok.extern.slf4j.Slf4j;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;

import jakarta.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/post")
@Tag(name = "帖子控制器")
@Slf4j
public class PostController {

  @Resource
  private PostService postService;

  @GetMapping("/list")
  @Operation(summary = "获取帖子列表（支持排序）")
  public Result<List<GetPostListVO>> getPostList(
      @RequestParam(value = "sortType", defaultValue = "0") Integer sortType) {
    try {
      PostListQueryDTO queryParam = new PostListQueryDTO();
      queryParam.setSortType(sortType);
      
      if (!queryParam.isValid()) {
        return Result.failure(400, "排序参数不合法");
      }
      
      List<GetPostListVO> postList = postService.getPostListWithSort(queryParam);
      return Result.success(postList);
    } catch (Exception e) {
      log.error("获取帖子列表失败", e);
      return Result.failure(500, "获取帖子列表失败: " + e.getMessage());
    }
  }

  /**
   * 根据类型获取帖子列表（支持排序）
   * 
   * @param type 帖子类型
   * @param sortType 排序类型（0-热度，1-时间，2-点赞）
   * @return 帖子列表
   */
  @GetMapping("/list/type/{type}")
  @Operation(summary = "根据类型获取帖子列表（支持排序）")
  public Result<List<GetPostListVO>> getPostListByType(
      @PathVariable Integer type,
      @RequestParam(value = "sortType", defaultValue = "0") Integer sortType) {
    try {
      PostListQueryDTO queryParam = new PostListQueryDTO();
      queryParam.setType(type);
      queryParam.setSortType(sortType);
      
      if (!queryParam.isValid()) {
        return Result.failure(400, "查询参数不合法");
      }
      
      List<GetPostListVO> postList = postService.getPostListWithSort(queryParam);
      return Result.success(postList);
    } catch (Exception e) {
      log.error("获取帖子列表失败", e);
      return Result.failure(500, "获取帖子列表失败: " + e.getMessage());
    }
  }

  /**
   * 点赞帖子
   * 
   * @param postId 帖子ID
   * @param userId 用户ID
   * @return 点赞结果
   */
  @PostMapping("/like/{postId}/{userId}")
  @Operation(summary = "点赞帖子")
  public Result<PostLikeVO> likePost(@PathVariable Integer postId, @PathVariable Integer userId) {
    try {
      PostLikeVO likeVO = postService.likePost(postId, userId);
      return Result.success(likeVO);
    } catch (RuntimeException e) {
      log.error("点赞失败: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("点赞失败", e);
      return Result.failure(500, "点赞失败: " + e.getMessage());
    }
  }

  /**
   * 获取帖子详情
   * 
   * @param postId 帖子ID
   * @return 帖子详情
   */
  @GetMapping("/query/{postId}")
  @Operation(summary = "获取帖子详情")
  public Result<PostDetailVO> getPostDetail(@PathVariable Integer postId) {
    try {
      PostDetailVO postDetail = postService.getPostDetail(postId);
      return Result.success(postDetail);
    } catch (RuntimeException e) {
      log.error("获取帖子详情失败: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("获取帖子详情失败", e);
      return Result.failure(500, "获取帖子详情失败: " + e.getMessage());
    }
  }

  /**
   * 发布帖子
   * 
   * @param createPostDTO 帖子信息
   * @return 帖子ID
   */
  @PostMapping("/create")
  @Operation(summary = "发布帖子")
  public Result<Integer> createPost(@RequestBody CreatePostDTO createPostDTO) {
    try {
      // 如果type为null，设置默认值0
      if (createPostDTO.getType() == null) {
        createPostDTO.setType(0);
      }
      // 验证type值是否合法
      if (createPostDTO.getType() < 0 || createPostDTO.getType() > 10) {
        return Result.failure(400, "帖子类型不合法");
      }
      Integer postId = postService.createPost(createPostDTO);
      return Result.success(postId);
    } catch (RuntimeException e) {
      log.error("发布帖子失败: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("发布帖子失败", e);
      return Result.failure(500, "发布帖子失败: " + e.getMessage());
    }
  }

  /**
   * 发表评论
   * 
   * @param createCommentDTO 评论信息
   * @return 评论详情
   */
  @PostMapping("/comment")
  @Operation(summary = "发表评论")
  public Result<CommentVO> createComment(@RequestBody CreateCommentDTO createCommentDTO) {
    try {
      CommentVO comment = postService.createComment(createCommentDTO);
      return Result.success(comment);
    } catch (RuntimeException e) {
      log.error("发表评论失败: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("发表评论失败", e);
      return Result.failure(500, "发表评论失败: " + e.getMessage());
    }
  }

  /**
   * 删除评论
   * 
   * @param commentId 评论ID
   * @param userId    用户ID
   * @return 删除结果
   */
  @DeleteMapping("/comment/{commentId}/{userId}")
  @Operation(summary = "删除评论")
  public Result<Void> deleteComment(@PathVariable Integer commentId, @PathVariable Integer userId) {
    try {
      boolean success = postService.deleteComment(commentId, userId);
      if (success) {
        return Result.success();
      } else {
        return Result.failure(500, "删除评论失败");
      }
    } catch (RuntimeException e) {
      log.error("删除评论失败: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("删除评论失败", e);
      return Result.failure(500, "删除评论失败: " + e.getMessage());
    }
  }

  /**
   * 收藏帖子
   * 
   * @param postId 帖子ID
   * @param userId 用户ID
   * @return 收藏结果
   */
  @PostMapping("/collect/{postId}/{userId}")
  @Operation(summary = "收藏帖子")
  public Result<PostCollectVO> collectPost(@PathVariable Integer postId, @PathVariable Integer userId) {
    try {
      PostCollectVO collectVO = postService.collectPost(postId, userId);
      return Result.success(collectVO);
    } catch (RuntimeException e) {
      log.error("收藏失败: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("收藏失败", e);
      return Result.failure(500, "收藏失败: " + e.getMessage());
    }
  }

  /**
   * 删除帖子
   * 
   * @param postId 帖子ID
   * @param userId 当前用户ID
   * @return 删除结果
   */
  @DeleteMapping("/{postId}/{userId}")
  @Operation(summary = "删除帖子")
  public Result<Boolean> deletePost(@PathVariable Integer postId, @PathVariable Integer userId) {
    try {
      if (postId == null || postId <= 0) {
        return Result.failure(400, "帖子ID不合法");
      }
      if (userId == null || userId <= 0) {
        return Result.failure(400, "用户ID不合法");
      }

      boolean success = postService.deletePost(postId, userId);
      return success ? Result.success(true) : Result.failure(500, "删除帖子失败");
    } catch (IllegalArgumentException e) {
      log.error("删除帖子参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("删除帖子失败", e);
      return Result.failure(500, "删除帖子失败: " + e.getMessage());
    }
  }

  /**
   * 举报帖子
   * 
   * @param reportDTO 举报信息
   * @return 举报结果
   */
  @PostMapping("/report")
  @Operation(summary = "举报帖子")
  public Result<Boolean> reportPost(@RequestBody PostReportDTO reportDTO) {
    try {
      // 参数校验
      if (reportDTO.getPostId() == null || reportDTO.getPostId() <= 0) {
        return Result.failure(400, "帖子ID不合法");
      }
      if (reportDTO.getUserId() == null || reportDTO.getUserId() <= 0) {
        return Result.failure(400, "用户ID不合法");
      }
      if (reportDTO.getReason() == null || reportDTO.getReason().trim().isEmpty()) {
        return Result.failure(400, "举报原因不能为空");
      }

      boolean success = postService.reportPost(reportDTO);
      return success ? Result.success(true) : Result.failure(500, "举报失败");
    } catch (IllegalArgumentException e) {
      log.error("举报帖子参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("举报帖子失败", e);
      return Result.failure(500, "举报帖子失败: " + e.getMessage());
    }
  }

  /**
   * 获取被举报的帖子列表
   * 
   * @return 被举报的帖子列表
   */
  @GetMapping("/reported/list")
  @Operation(summary = "获取被举报的帖子列表")
  public Result<List<ReportedPostVO>> getReportedPosts() {
    try {
      List<ReportedPostVO> reportedPosts = postService.getReportedPosts();
      return Result.success(reportedPosts);
    } catch (Exception e) {
      log.error("获取被举报帖子列表失败", e);
      return Result.failure(500, "获取被举报帖子列表失败: " + e.getMessage());
    }
  }

  /**
   * 通过举报（认为举报不成立）
   * 
   * @param reportId     举报记录ID
   * @param handleResult 处理结果说明
   * @return 处理结果
   */
  @PostMapping("/report/approve/{reportId}")
  @Operation(summary = "通过举报")
  public Result<Boolean> approveReport(
      @PathVariable Integer reportId,
      @RequestParam String handleResult) {
    try {
      if (reportId == null || reportId <= 0) {
        return Result.failure(400, "举报ID不合法");
      }
      if (handleResult == null || handleResult.trim().isEmpty()) {
        return Result.failure(400, "处理结果说明不能为空");
      }

      boolean success = postService.approveReport(reportId, handleResult);
      return success ? Result.success(true) : Result.failure(500, "处理举报失败");
    } catch (IllegalArgumentException e) {
      log.error("处理举报参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("处理举报失败", e);
      return Result.failure(500, "处理举报失败: " + e.getMessage());
    }
  }

  /**
   * 处理举报（删除帖子）
   * 
   * @param reportId     举报记录ID
   * @param handleResult 处理结果说明
   * @return 处理结果
   */
  @PostMapping("/report/reject/{reportId}")
  @Operation(summary = "处理举报（删除帖子）")
  public Result<Boolean> rejectAndDeletePost(
      @PathVariable Integer reportId,
      @RequestParam String handleResult) {
    try {
      if (reportId == null || reportId <= 0) {
        return Result.failure(400, "举报ID不合法");
      }
      if (handleResult == null || handleResult.trim().isEmpty()) {
        return Result.failure(400, "处理结果说明不能为空");
      }

      boolean success = postService.rejectAndDeletePost(reportId, handleResult);
      return success ? Result.success(true) : Result.failure(500, "处理举报失败");
    } catch (IllegalArgumentException e) {
      log.error("处理举报参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("处理举报失败", e);
      return Result.failure(500, "处理举报失败: " + e.getMessage());
    }
  }

  /**
   * 获取用户收藏的帖子列表
   * 
   * @param userId 用户ID
   * @return 收藏的帖子列表
   */
  @GetMapping("/collection/list/{userId}")
  @Operation(summary = "获取用户收藏的帖子列表")
  public Result<List<GetPostListVO>> getUserCollectionList(@PathVariable Integer userId) {
    try {
      if (userId == null || userId <= 0) {
        return Result.failure(400, "用户ID不合法");
      }

      List<GetPostListVO> collectionList = postService.getUserCollectionList(userId);
      return Result.success(collectionList);
    } catch (IllegalArgumentException e) {
      log.error("获取收藏列表参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("获取收藏列表失败", e);
      return Result.failure(500, "获取收藏列表失败: " + e.getMessage());
    }
  }

  /**
   * 获取用户发布的帖子列表
   * 
   * @param userId 用户ID
   * @return 发布的帖子列表
   */
  @GetMapping("/publish/list/{userId}")
  @Operation(summary = "获取用户发布的帖子列表")
  public Result<List<GetPostListVO>> getUserPublishList(@PathVariable Integer userId) {
    try {
      if (userId == null || userId <= 0) {
        return Result.failure(400, "用户ID不合法");
      }

      List<GetPostListVO> publishList = postService.getUserPublishList(userId);
      return Result.success(publishList);
    } catch (IllegalArgumentException e) {
      log.error("获取发布列表参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("获取发布列表失败", e);
      return Result.failure(500, "获取发布列表失败: " + e.getMessage());
    }
  }

  /**
   * 获取用户点赞的帖子列表
   * 
   * @param userId 用户ID
   * @return 点赞的帖子列表
   */
  @GetMapping("/like/list/{userId}")
  @Operation(summary = "获取用户点赞的帖子列表")
  public Result<List<GetPostListVO>> getUserLikeList(@PathVariable Integer userId) {
    try {
      if (userId == null || userId <= 0) {
        return Result.failure(400, "用户ID不合法");
      }

      List<GetPostListVO> likeList = postService.getUserLikeList(userId);
      return Result.success(likeList);
    } catch (IllegalArgumentException e) {
      log.error("获取点赞列表参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("获取点赞列表失败", e);
      return Result.failure(500, "获取点赞列表失败: " + e.getMessage());
    }
  }

  /**
   * 管理员获取应该审核的帖子列表(postStatus=1)
   * 
   * @return 待审核的帖子列表
   */
  @GetMapping("/pending/list")
  @Operation(summary = "获取待审核的帖子列表")
  public Result<List<GetPostListVO>> getPendingPosts() {
    try {
      List<GetPostListVO> pendingPosts = postService.getPendingPosts();
      return Result.success(pendingPosts);
    } catch (Exception e) {
      log.error("获取待审核帖子列表失败", e);
      return Result.failure(500, "获取待审核帖子列表失败: " + e.getMessage());
    }
  }

  /**
   * 管理员通过审核(postStatus=3)
   * 
   * @param postId  帖子ID
   * @param adminId 管理员ID
   * @return 审核结果
   */
  @PostMapping("/approve/{postId}/{adminId}")
  @Operation(summary = "管理员通过审核")
  public Result<Boolean> approvePost(
      @PathVariable Integer postId,
      @PathVariable Integer adminId) {
    try {
      if (postId == null || postId <= 0) {
        return Result.failure(400, "帖子ID不合法");
      }
      if (adminId == null || adminId <= 0) {
        return Result.failure(400, "管理员ID不合法");
      }

      boolean success = postService.approvePost(postId, adminId);
      return success ? Result.success(true) : Result.failure(500, "审核操作失败");
    } catch (IllegalArgumentException e) {
      log.error("审核参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("审核操作失败", e);
      return Result.failure(500, "审核操作失败: " + e.getMessage());
    }
  }

  /**
   * 管理员不通过审核(postStatus=2)
   * 
   * @param postId  帖子ID
   * @param adminId 管理员ID
   * @param reason  拒绝原因
   * @return 审核结果
   */
  @PostMapping("/reject/{postId}/{adminId}")
  @Operation(summary = "管理员不通过审核")
  public Result<Boolean> rejectPost(
      @PathVariable Integer postId,
      @PathVariable Integer adminId,
      @RequestParam String reason) {
    try {
      if (postId == null || postId <= 0) {
        return Result.failure(400, "帖子ID不合法");
      }
      if (adminId == null || adminId <= 0) {
        return Result.failure(400, "管理员ID不合法");
      }
      if (reason == null || reason.trim().isEmpty()) {
        return Result.failure(400, "拒绝原因不能为空");
      }

      boolean success = postService.rejectPost(postId, adminId, reason);
      return success ? Result.success(true) : Result.failure(500, "审核操作失败");
    } catch (IllegalArgumentException e) {
      log.error("审核参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("审核操作失败", e);
      return Result.failure(500, "审核操作失败: " + e.getMessage());
    }
  }

  /**
   * 增加帖子热度
   * 
   * @param increasePostHeatDTO 增加热度请求参数
   * @return 热度操作结果
   */
  @PostMapping("/heat/increase")
  @Operation(summary = "增加帖子热度")
  public Result<PostHeatVO> increasePostHeat(@Valid @RequestBody IncreasePostHeatDTO increasePostHeatDTO) {
    try {
      PostHeatVO heatVO = postService.increasePostHeat(increasePostHeatDTO);
      return Result.success(heatVO);
    } catch (IllegalArgumentException e) {
      log.error("增加帖子热度参数错误: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (RuntimeException e) {
      log.error("增加帖子热度业务异常: {}", e.getMessage());
      return Result.failure(400, e.getMessage());
    } catch (Exception e) {
      log.error("增加帖子热度失败", e);
      return Result.failure(500, "增加帖子热度失败: " + e.getMessage());
    }
  }

}
